package postgres

import (
	"context"
	"gorm.io/gorm"
	"manager/errors"
	"manager/model"
	"manager/model/entity"
	"manager/utils"
)

var MessageNotify = &messageNotify{}

type messageNotify struct{}

// Create 创建
func (a *messageNotify) Create(ctx context.Context, m *entity.MessageNotify) (int64, error) {
	err := GetDB(ctx).Create(m).Error
	return m.Id, err
}

// Find 查找详情
func (a *messageNotify) Find(ctx context.Context, in *model.MessageNotifyInfoRequest) (*entity.MessageNotify, error) {
	e := &entity.MessageNotify{}

	q := GetDB(ctx).Model(&entity.MessageNotify{})

	if in.Id > 0 {
		err := q.First(&e, in.Id).Error
		return e, err
	}

	count := 0

	if in.EbikeId != nil {

		q = q.Where("ebike_id = ?", in.EbikeId)

		count++
	}

	if in.EbikeName != nil {

		q = q.Where("ebike_name like ?", in.EbikeName)

		count++
	}

	if in.MessageType != nil {

		q = q.Where("message_type = ?", in.MessageType)

		count++
	}

	if in.Title != nil {

		q = q.Where("title like ?", in.Title)

		count++
	}

	if in.Content != nil {

		q = q.Where("content like ?", in.Content)

		count++
	}

	if in.Flag != nil {

		q = q.Where("flag = ?", in.Flag)

		count++
	}

	if in.UpdatedAt != nil {

		q = q.Where("updated_at = ?", in.UpdatedAt)

		count++
	}

	if in.Extend != "" {
		q = q.Where("extend = ?", in.Extend)
	}

	if in.TimeStamp != nil && *in.TimeStamp > 0 {
		zeroTime := utils.NowDayUnix(*in.TimeStamp)
		endTime := zeroTime + 86400
		q = q.Where("created_at >= ? and created_at < ?", zeroTime, endTime)
	}

	if count == 0 {
		return e, errors.New("condition illegal")
	}

	err := q.First(&e).Error
	return e, err
}

// Update 更新
func (a *messageNotify) Update(ctx context.Context, in *model.MessageNotifyUpdateRequest, dict map[string]interface{}) error {
	if in.TimeStamp != nil && *in.TimeStamp > 0 {
		zeroTime := utils.NowDayUnix(*in.TimeStamp)
		endTime := zeroTime + 86400
		if in.MessageType != nil && *in.MessageType == 3 {
			return GetDB(ctx).Model(&entity.MessageNotify{}).Where("created_at >= ? and created_at < ? and user_id = ? and message_type = ?", zeroTime, endTime, in.UserId, in.MessageType).Update("flag", 1).Error
		}

		if len(in.EbikeIds) == 0 {
			return errors.New("ebike_ids is empty")
		}

		return GetDB(ctx).Model(&entity.MessageNotify{}).Where("created_at >= ? and created_at < ? and ebike_id in ? and message_type = ?", zeroTime, endTime, in.EbikeIds, in.MessageType).Update("flag", 1).Error
	}

	if in.Id <= 0 {
		return gorm.ErrRecordNotFound
	}

	return GetDB(ctx).Model(&entity.MessageNotify{}).Where("id = ?", in.Id).Updates(dict).Error
}

// Delete 删除
func (a *messageNotify) Delete(ctx context.Context, id int64) error {
	return GetDB(ctx).Delete(&entity.MessageNotify{}, id).Error
}

// List 列表查询
func (a *messageNotify) List(ctx context.Context, in *model.MessageNotifyListRequest) (int, []*entity.MessageNotify, error) {
	var (
		q              = GetDB(ctx).Model(&entity.MessageNotify{})
		err            error
		total          int64
		messageNotifys []*entity.MessageNotify
	)

	// 查询
	if in.UserId > 0 && in.MessageType != nil && *in.MessageType == 3 {
		q = q.Where("user_id = ?", in.UserId)
	}

	if len(in.EbikeIds) > 0 {
		q = q.Where("ebike_id in (?)", in.EbikeIds)
	}

	if in.EbikeId != nil {

		q = q.Where("ebike_id = ?", in.EbikeId)

	}

	if in.EbikeName != nil {

		q = q.Where("ebike_name like ?", in.EbikeName)

	}

	if in.MessageType != nil {

		q = q.Where("message_type = ?", in.MessageType)

	}

	if in.Title != nil {

		q = q.Where("title like ?", in.Title)

	}

	if in.Content != nil {

		q = q.Where("content like ?", in.Content)

	}

	if in.Flag != nil {

		q = q.Where("flag = ?", in.Flag)

	}

	if in.UpdatedAt != nil {

		q = q.Where("updated_at = ?", in.UpdatedAt)

	}

	if in.TimeStamp != nil && *in.TimeStamp > 0 {
		zeroTime := utils.NowDayUnix(*in.TimeStamp)
		endTime := zeroTime + 86400
		q = q.Where("created_at >= ? and created_at < ?", zeroTime, endTime)
	}

	if err = q.Count(&total).Error; err != nil {
		return 0, nil, err
	}
	if err = q.Order("created_at desc").Limit(in.Size).Offset((in.Index - 1) * in.Size).Find(&messageNotifys).Error; err != nil {
		return 0, nil, err
	}
	return int(total), messageNotifys, nil
}

// ExecTransaction db事务执行
func (a *messageNotify) ExecTransaction(ctx context.Context, callback func(ctx context.Context) error) error {
	return GetDB(ctx).Transaction(func(tx *gorm.DB) error {
		ctx = context.WithValue(ctx, DBCONTEXTKEY, tx)
		return callback(ctx)
	})
}
